from django.shortcuts import render
from django.views import View
from django.http import JsonResponse
from django.conf import settings
from django.contrib.auth import login

import json,re
from django_redis import get_redis_connection
from users.models import User

from QQLoginTool.QQtool import OAuthQQ
from oauth.models import OAuthQQUser
from meiduo_mall.utils.secret import SecretOAuth
# Create your views here.


class QQURLView(View):

    # QQ登陆接口一：获取扫码登陆页面url
    def get(self, request):
        # 1、提取参数
        next = request.GET.get('next') # 前端传参用于标记登陆成功之后返回的页面
        # 2、校验参数
        # 3、业务数据处理 —— 获取扫码页面url
        # TODO： 使用QQLoginTool工具来构造url
        oauth = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID, # 文档中的appid即应用id
            client_secret=settings.QQ_CLIENT_SECRET, # 文档中的appkey即应用密钥
            redirect_uri=settings.QQ_REDIRECT_URI, # QQ身份验证之后用户跳转回美多的页面链接
            state=next, # 整个登陆流程结束，浏览器跳转回的页面
        )

        # 获取登陆页面url
        login_url = oauth.get_qq_url()

        # 4、构建响应
        return JsonResponse({
            'code': 0, 'errmsg': 'ok', 'login_url': login_url
        })


class QQUserView(View):

    # QQ登陆接口二：获取openid
    def get(self, request):
        # 1、提取参数
        # code是QQ服务器返回给浏览器，浏览器请求接口2携带过来的
        code = request.GET.get('code')

        # 2、校验参数
        # 3、业务数据处理(获取openid)
        oauth = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,  # 文档中的appid即应用id
            client_secret=settings.QQ_CLIENT_SECRET,  # 文档中的appkey即应用密钥
            redirect_uri=settings.QQ_REDIRECT_URI,  # QQ身份验证之后用户跳转回美多的页面链接
            state=None
        )

        try:
            # TODO: 根据code，获取Access Token
            access_token = oauth.get_access_token(code)
            # TODO: 根据Access Token，获取OpenID
            openid = oauth.get_open_id(access_token)
        except Exception as e:
            print(e) # 校验code获取Access Token或者获取OpenID失败
            return JsonResponse({'code': 400, 'errmsg': 'QQ登陆失败'})

        # 4、构建响应(已绑定，未绑定两种情况)
        try:
            oauth_user = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist as e:
            # 根据openid找不到数据，说明未绑定
            # TODO: 把openid加密构造响应返回
            access_token = SecretOAuth().dumps({'openid':openid})
            return JsonResponse({
                'code': 400, # 如果用户未绑定，我们返回code400，前端定向到绑定页面
                'errmsg': '未绑定',
                'access_token': access_token, # 加密后的openid
            })
        else:
            # 没有抛出异常，根据openid找到了数据，说明已绑定
            # TODO: 构造正常的响应返回 —— 属于QQ登陆成功
            user = oauth_user.user # 获取当前openid绑定的美多商城用户对象
            login(request, user)

            response = JsonResponse({
                'code': 0, 'errmsg': '恭喜，QQ登陆成功'
            })

            response.set_cookie(
                'username',
                user.username,
                max_age=14*3600*24
            )

            # TODO: 合并购物车
            from carts.utils import merge_cart_cookie_to_redis
            response = merge_cart_cookie_to_redis(request, response)

            return response

    # QQ登陆接口三：账号绑定
    def post(self, request):
        # 1、提取参数
        data = json.loads(request.body.decode())

        mobile = data.get('mobile')
        password = data.get('password')
        sms_code = data.get('sms_code')

        # 密文openid字符串
        access_token = data.get('access_token')

        # 2、校验参数
        if not all([mobile, password, sms_code, access_token]):
            return JsonResponse({'code': 400, 'errmsg': '缺少必要参数'})
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'code': 400, 'errmsg': 'mobile格式有误!'})
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return JsonResponse({'code': 400, 'errmsg': 'password格式有误!'})

        conn = get_redis_connection('verify_code') # 2号
        redis_sms_code = conn.get('sms_%s'%mobile)
        if not redis_sms_code:
            return JsonResponse({'code': 400, 'errmsg': '短信验证码过期'})
        if sms_code != redis_sms_code.decode():
            return JsonResponse({'code': 400, 'errmsg': '短信验证码输入错误'})

        # TODO: 解密openid
        content_dict = SecretOAuth().loads(access_token)
        if content_dict is None:
            # 解密失败
            return JsonResponse({'code': 400, 'errmsg': 'openid有误'})
        openid = content_dict.get('openid')

        # 3、业务数据处理(情况一，账号存在密码正确直接绑定；情况二，账号不存在则新建绑定)
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist as e:
            # TODO: 用户未注册美多商城账号 —— 账号不存在则新建绑定
            user = User.objects.create_user(mobile=mobile, username=mobile, password=password)
            OAuthQQUser.objects.create(user=user, openid=openid)
        else:
            # TODO: 用户美多商城账号已注册 —— 账号存在密码正确直接绑定
            if not user.check_password(password):
                return JsonResponse({'code': 400, 'errmsg': '密码错误'})
            OAuthQQUser.objects.create(user=user, openid=openid)

        # 4、构建响应
        login(request, user)
        response = JsonResponse({'code': 0, 'errmsg': 'ok'})
        response.set_cookie('username', user.username, max_age=3600*14*24)
        # TODO: 合并购物车
        from carts.utils import merge_cart_cookie_to_redis
        response = merge_cart_cookie_to_redis(request, response)
        return response















